#include "stdafx.h"

#include "thermal_jacobian_matrix.h"

namespace blue_sky{

	//! constructor
	template <class strategy_t>
	thermal_jacobian_matrix<strategy_t>::thermal_jacobian_matrix (bs_type_ctor_param param)
		: jacobian_matrix(param), solver_(BS_KERNEL.create_object(cgs_solver<strategy_t>::bs_type()))
	{
	}

	template <class strategy_t>
	thermal_jacobian_matrix<strategy_t>::thermal_jacobian_matrix (const this_t & src)
		: bs_refcounter (src), base_t(src)
	{
		if (&src != this)
			*this = src;
	}

	template <class strategy_t>
	void
	thermal_jacobian_matrix<strategy_t>::
	mv_minus_mmv (index_t nb, rhs_item_t* sp_block, item_t* sol_vec, item_t* sec_sol, rhs_item_t* ss_block, rhs_item_t* sec_rhs){
		for (index_t i = 0; i < n_sec_vars; i++){
			rhs_item_t sum = 0;			
			for (index_t j = 0; j < nb; j++){
				sum += (sp_block[i * nb + j] * sol_vec[j]) / ss_block[i];
			}
			sec_sol[i] = sec_rhs[i] / ss_block[i] - sum;
		}
	}

	/**
	* @brief restore solution for secondary variables
	*        Xs = Dss * Bs - Dss * Asp * Xp
	*        Xs -- (OUTPUT) solution vector for secondary variables
	*        Dss -- (Ass)^(-1)
	*        Bs -- rhs vector for secondary variables
	*        Xp -- solution vector for primary variables
	*
	* @return 0 if success
	*/
	template <class strategy_t>
	void
	thermal_jacobian_matrix<strategy_t>::restore_sec_solution ()
	{
		prepare_ss_matrix();
		solver_->solve(merged_ss_matrix, sec_rhs, sec_solution); //only for ps and sp equals to zero
		/*
		rhs_item_t *sp_block = 0;
		item_t *sol_block = 0;
		rhs_item_t *ss_block;

		if (n_sec_vars > 0 && regular_matrix->get_rows_ptr ().size ())
		{
			index_t nb = regular_matrix->n_block_size;
			for (index_t i = 0, cnt = (index_t)regular_matrix->get_rows_ptr ().size (); i < cnt - 1; ++i)
			{
				sp_block = &sp_diagonal[n_sec_vars * nb * i];
				sol_block = &solution[nb * i];
				ss_block = &ss_diag[n_sec_vars * n_sec_vars * i];
				item_t *sec_sol = &sec_solution[i * n_sec_vars];
				
				mv_minus_mmv(nb, sp_block, sol_block, sec_sol, ss_block, &sec_rhs[i * n_sec_vars]);
			}
		}*/
	}

	BLUE_SKY_TYPE_STD_CREATE_T_DEF(thermal_jacobian_matrix, (class));
	BLUE_SKY_TYPE_STD_COPY_T_DEF(thermal_jacobian_matrix, (class));

	
	BLUE_SKY_TYPE_IMPL_T_EXT(1, (thermal_jacobian_matrix<base_strategy_fi>) , 1, (jacobian_matrix<base_strategy_fi>), "thermal_jacobian_matrix_fi", "thermal_jacobian_matrix_base-float-int", "Thermal_jacobian_matrix_base with float items and integer indexes", false);
	BLUE_SKY_TYPE_IMPL_T_EXT(1, (thermal_jacobian_matrix<base_strategy_di>) , 1, (jacobian_matrix<base_strategy_di>), "thermal_jacobian_matrix_di", "thermal_jacobian_matrix_base-double-int", "Thermal_jacobian_matrix_base with double items and integer indexes", false);
	BLUE_SKY_TYPE_IMPL_T_EXT(1, (thermal_jacobian_matrix<base_strategy_mixi>) , 1, (jacobian_matrix<base_strategy_mixi>), "thermal_jacobian_matrix_mixi", "thermal_jacobian_matrix_base-mix-int", "Thermal_jacobian_matrix_base with double items and integer indexes", false);

}